package com.i2works.smartluolong.utils.common;


import com.google.common.collect.Lists;
import com.google.common.io.Files;
import com.i2works.smartluolong.utils.base.*;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.xiaoleilu.hutool.util.RandomUtil;
import com.xiaoleilu.hutool.util.ReflectUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 网站前台工具类
 *
 * @author Liu Yutao <koal@vip.qq.com>
 * @date 2016/11/3 13:04
 */
@Component
public class WebUtil implements Serializable {

    /**
     * 字符串截取
     */
    public static String cut(String value, Integer number) {
        if (StringUtils.isNotBlank(value)) {
            //正则判断是否为数字
            if (!NumberUtils.isDigits(String.valueOf(number))) {
                number = 0;
            }
            if (value.length() <= number) {
                number = value.length();
            }
            return StringUtils.substring(value, 0, number);
        } else {
            return null;
        }

    }

    /**
     * 判断是否为空
     */
    public static <T> T isNull(T value, T defaultValue) {
        if (StringUtils.isNotBlank(String.valueOf(value))) {
            return value;
        } else {
            return defaultValue;
        }
    }


    /**
     * 删除html代码
     */
    public static String text(String value) {
        if (StringUtils.isNotBlank(value)) {
            return value.replaceAll("<(/*?)(\\w+?)>", "");
        }
        return null;
    }


    /**
     * 删除中英文符号
     */
    public static String delSymbol(String value) {
        if (StringUtils.isNotBlank(value)) {
            //return value.replaceAll("[\\/‘’“”<>\"'_\\s]", "");
            return value.replaceAll("[\\/‘’“”<>\"'_]", "");
        }
        return null;
    }

    /**
     * URL加密
     */
    public static String urlEncoder(String value) {
        try {
            if (StringUtils.isNotBlank(value)) {
                return URLEncoder.encode(value, "utf-8");
            }
        } catch (Exception e) {
            System.err.println("webutil.URL加密异常:" + e.getMessage());
        }
        return null;
    }


    /**
     * JS中状态传参
     */
    public static Integer status(Integer status) {
        return status;
    }


    /**
     * 获取当前URL链接
     */
    public static String URI(HttpServletRequest request) {
        return request.getRequestURI();
    }


    /**
     * 获取当前URL链接
     */
    public static String URL(HttpServletRequest request) {
        return request.getRequestURL().toString();
    }

    /**
     * 获取域名
     */
    public static String domain(HttpServletRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(request.getScheme()).append("://").append(request.getServerName());
        if (request.getServerPort() != 80 || request.getServerPort() != 443) {
            stringBuilder.append(":").append(request.getServerPort()).append("/");
        }
        return stringBuilder.toString();
    }


    /**
     * cookie名称
     */
    public static String sid(String domain) {
        if (StringUtils.isNotBlank(domain) && domain.contains(".")) {
            return domain.substring(domain.indexOf(".") + 1, domain.lastIndexOf("."));
        }
        return RandomUtil.randomNumbers(8);
    }


    /**
     * 菜单比较
     */
    public static boolean menuContains(String str, String pathStr) {
        String substr = str.substring(0, str.indexOf("/", str.indexOf("/") + 1));
        return pathStr.contains(substr);
    }

    /**
     * 获取集合
     */
    public static Object getValue(List list, Integer index) {
        Object o = list.get(index);
        return list.get(index);
    }

    /**
     * 获取时间
     */
    public static String dateTime(Date date) {
        return DateUtils.get(date, DateConstant.ALL);
    }

    /**
     * 获取时间
     */
    public static String date(Date date) {
        return DateUtils.get(date, DateConstant.YYYY_MM_DD);
    }

    /**
     * 获取时间
     */
    public static String dateObj(Date date, String format) {
        return DateUtils.get(date, format);
    }

    /**
     * 字符串对比
     */
    public boolean contain(String str, String key) {
        //throw new NullPointerException("Error: contain(null)");
        return str != null && str.contains(key);
    }


    /**
     * 字符串是否包含在集合中（根据字符串英文逗号切割）对比
     */
    public boolean containList(String str, String key) {
        if (StringUtils.isNotBlank(str)) {
            String[] split = str.split(",");
            List<String> asList = Arrays.asList(split);
            return asList.contains(key);
        }
        return false;
    }

    /**
     * 获取文件名
     */
    public static String fileName(String value) {
        String fileName = Files.getNameWithoutExtension(value);
        String suffix = Files.getFileExtension(value);
        return fileName + "." + suffix;
    }


    /**
     * 工商人员角色
     */
    public static String memberRole(Integer key) {
        return String.valueOf(getEnumValue(CompanyMemberRoleEnum.class, key, null, null));
    }


    /**
     * 证件类型
     *
     * @param cardType 1身份证，2营业执照，3其他有效证件
     */
    public static String getCardType(Integer cardType) {
        String result;
        switch (cardType) {
            case 1:
                result = "身份证";
                break;
            case 2:
                result = "营业执照";
                break;
            case 3:
                result = "其他有效证件";
                break;
            default:
                result = "身份证";
                break;
        }
        return result;
    }


    /**
     * 学历
     */
    public static String memberEdu(Integer key) {
        return String.valueOf(getEnumValue(EducationEnum.class, key, null, null));
    }


    /**
     * 工商股东出资方式
     */
    public static String memberInvestmentMode(String key) {
        List<String> result = Lists.newArrayList();
        List<String> list = BaseUtils.strToList(key, ",");
        if (list != null && list.size() > 0) {
            for (String str : list) {
                result.add(String.valueOf(getEnumValue(CompanyMemberInvestmentModeEnum.class, Integer.valueOf(str), null, null)));
            }
        }
        return BaseUtils.listToStr(result, "、");
    }


    /**
     * 一体机个人证明(获取事项名称)
     */
    public static String personalItemType(String key) {
        Object Result = getEnumValue(PersonalItemTypeEnum.class, key, null, "value");
        return String.valueOf(Result);
    }


    /**
     * 一体机个人证明(获取事项单位)
     */
    public static String personalLeader(String key) {
        Object Result = getEnumValue(PersonalItemTypeEnum.class, key, null, "leader");
        return String.valueOf(Result);
    }

    /**
     * 多少年后
     */
    public static String yearsLater(Integer years) {
        return getYearsLater(years, null);
    }

    /**
     * 多少年后
     */
    public static String yearsLater(Integer years, String format) {
        return getYearsLater(years, format);
    }

    private static String getYearsLater(Integer years, String format) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.YEAR, years);
        if (StringUtils.isNotBlank(format)) {
            return DateUtils.get(c.getTime(), format);
        }
        return DateUtils.get(c.getTime(), "yyyy年MM月dd日");
    }


    /**
     * 工商办理 - 法定代表人职务
     */
    public static String memberJob(Integer key) {
        return String.valueOf(getEnumValue(CompanyMemberJobEnum.class, key, null, null));
    }

    /**
     * 工商办理 - 公司成员角色(分开)
     *
     * @param key 身份ID编号
     */
    public static String memberOneIdentity(Integer key) {
        return String.valueOf(getEnumValue(CompanyMemberIdentityEnum.class, key, null, null));
    }

    /**
     * 工商办理 - 公司成员角色（合并）
     *
     * @param 身份ID字符串（1,2,3,4）
     */
    public static String memberIdentity(String key) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        List<String> result = Lists.newArrayList();
        List<String> list = BaseUtils.strToList(key, ",");
        if (list != null && list.size() > 0) {
            for (String str : list) {
                result.add(String.valueOf(getEnumValue(CompanyMemberIdentityEnum.class, Integer.valueOf(str), null, null)));
            }
        }
        return BaseUtils.listToStr(result, "、");
    }


    /**
     * 工商（申请，备案，变更）状态名称
     */
    public static String companyItemStatus(Integer key) {
        return itemStatus(key, CompanyStatusEnum.class);
    }

    /**
     * 个体户（申请，备案，变更）状态名称
     */
    public static String merchantItemStatus(Integer key) {
        return itemStatus(key, MerchantStatusEnum.class);
    }


    /**
     * 食药状态名称
     */
    public static String fooddrugItemStatus(Integer key) {
        return itemStatus(key, FooddrugStatusEnum.class);
    }

    /**
     * 残联状态名称
     */
    public static String disabilityItemStatus(Integer key) {
        return itemStatus(key, DisabilityStatusEnum.class);
    }

    /**
     * 报表排序名称
     */
    public static String reportOrderStatus(Integer key) {
        return itemStatus(key, ReportOrderEnum.class);
    }


    /**
     * 工作流-事项类型状态名称
     */
    public static String itemTypeValue(String key) {
        return String.valueOf(getEnumValue(FlowItemTypeEnum.class, key, "key", "value"));
    }


    /**
     * 通用状态名称获取工具
     */
    public static <E extends Enum<E>> String itemStatus(Integer key, Class<E> eEnum) {
        return String.valueOf(getEnumValue(eEnum, key, null, null));
    }


    /**
     * 获取枚举类的text值
     *
     * @param eEnum     枚举类
     * @param input     枚举类key的值
     * @param keyName   枚举类key的字段值
     * @param valueName 枚举类text的字段值
     */
    private static <E extends Enum<E>> Object getEnumValue(Class<E> eEnum, Object input, String keyName, String valueName) {
        if (StringUtils.isBlank(keyName)) {
            keyName = "key";
        }
        if (StringUtils.isBlank(valueName)) {
            valueName = "text";
        }
        List<E> enumList = EnumUtils.getEnumList(eEnum);
        for (E e : enumList) {
            Object key = ReflectUtil.getFieldValue(e, keyName);
            if (ObjectUtil.equal(key, input)) {
                return ReflectUtil.getFieldValue(e, valueName);
            }
        }
        return null;
    }

    /**
     * 获取枚举类
     *
     * @param eEnum     枚举类
     * @param input     枚举类key的值
     * @param keyName   枚举类key的字段值
     * @param valueName 枚举类text的字段值
     */
    public static <E extends Enum<E>> E getEnum(Class<E> eEnum, Object input, String keyName) {
        if (StringUtils.isBlank(keyName)) {
            keyName = "key";
        }
        List<E> enumList = EnumUtils.getEnumList(eEnum);
        for (E e : enumList) {
            Object key = ReflectUtil.getFieldValue(e, keyName);
            if (ObjectUtil.equal(key, input)) {
                return e;
            }
        }
        return null;
    }

    /**
     * 出资比例
     *
     * @param total   总金额
     * @param current 当前金额
     * @return String比例
     */
    public static String ratio(String totalString, String currentString) {
        if (StringUtils.isAnyBlank(totalString, currentString)) {
            return "0%";
        } else {
            BigDecimal current = BigDecimal.valueOf(Long.parseLong(currentString));
            BigDecimal total = BigDecimal.valueOf(Long.parseLong(totalString));
            BigDecimal divide = current.divide(total, 4, RoundingMode.HALF_UP);
            //下面将结果转化成百分比
            NumberFormat percent = NumberFormat.getPercentInstance();
            percent.setMaximumFractionDigits(2);
            return percent.format(divide.doubleValue());
        }
    }

    /**
     * 数组对比
     */
    public static boolean arrayContain(String[] oneStrs, String[] twoStrs) {
        if (ArrayUtils.isEmpty(oneStrs) && ArrayUtils.isEmpty(twoStrs)) {
            return true;
        }
        List<String> oneList = Arrays.asList(oneStrs);
        List<String> twoList = Arrays.asList(twoStrs);
        return oneList.size() == twoList.size() && oneList.containsAll(twoList);
    }

    /**
     * 数字金额转换中文金额
     *
     * @param value
     * @return
     */
    public static String number2Chs(String value) {
        BigDecimal bigMonney = NumberUtils.createBigDecimal(value).multiply(new BigDecimal(10000));
        return Number2ChsUtil.format(bigMonney);
    }

}
